using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace InputManagement
{
    public interface IInputService
    {
        event Action<bool> OnShoot;
        event Action<bool> OnSuperShoot;
        
    }

    public class InputManager : Microsoft.Xna.Framework.GameComponent, IInputService
    {
        public struct InputState
        {
            public int mouseX;
            public int mouseY;
            public bool shoot;
            public bool click;
            public bool exit;
            public bool pause;
            public bool restart;
            public bool quit;
            public bool save;
            public bool load;
            public Vector2 directionMove;
        }

        MouseState mCurrentState;
        MouseState mPreviousState;

        KeyboardState kCurrentState;
        KeyboardState kPreviousState;
        public static InputState inputState;

        public static InputState GetState()
        {
            return inputState;
        }

        public InputManager(Game game)
            : base(game)
        {
            game.Services.AddService(typeof(IInputService), this);
        }
                

        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(IInputService));
            base.Dispose(disposing);
        }

        /// <summary>
        /// Consente al componente del gioco di aggiornare se stesso.
        /// </summary>
        /// <param name="gameTime">Fornisce uno snapshot dei valori di temporizzazione.</param>
        public override void Update(GameTime gameTime)
        {
            mCurrentState = Mouse.GetState();
            kCurrentState = Keyboard.GetState();
            inputState.mouseX = mCurrentState.X;
            inputState.mouseY = mCurrentState.Y;
            inputState.directionMove = Vector2.Zero;
            
            if (OnShoot != null)
            {
                OnShoot(mCurrentState.LeftButton == ButtonState.Pressed);
            }

            if (OnSuperShoot != null)
            {
                OnSuperShoot(mCurrentState.RightButton == ButtonState.Released && mPreviousState.RightButton == ButtonState.Pressed);
            }
                    
            if (kCurrentState.IsKeyDown(Keys.W))
                inputState.directionMove -= Vector2.UnitY;
            if (kCurrentState.IsKeyDown(Keys.S))
                inputState.directionMove += Vector2.UnitY;
            if (kCurrentState.IsKeyDown(Keys.A))
                inputState.directionMove -= Vector2.UnitX;
            if (kCurrentState.IsKeyDown(Keys.D))
                inputState.directionMove += Vector2.UnitX;
            
            if (mCurrentState.LeftButton == ButtonState.Released && mPreviousState.LeftButton == ButtonState.Pressed)
                inputState.click = true;
            else
                inputState.click = false;

            if (kCurrentState.IsKeyUp(Keys.S) && kPreviousState.IsKeyDown(Keys.K))
                inputState.save = true;
            else
                inputState.save = false;

            if (kCurrentState.IsKeyUp(Keys.L) && kPreviousState.IsKeyDown(Keys.L))
                inputState.load = true;
            else
                inputState.load = false;
                        
            if (kCurrentState.IsKeyUp(Keys.Escape) && kPreviousState.IsKeyDown(Keys.Escape))
                inputState.exit = true;
            else
                inputState.exit = false;

            if (kCurrentState.IsKeyUp(Keys.P) && kPreviousState.IsKeyDown(Keys.P))
                inputState.pause = true;
            else
                inputState.pause = false;

            if (kCurrentState.IsKeyUp(Keys.R) && kPreviousState.IsKeyDown(Keys.R))
                inputState.restart = true;
            else
                inputState.restart = false;

            if (kCurrentState.IsKeyUp(Keys.Q) && kPreviousState.IsKeyDown(Keys.Q))
                inputState.quit = true;
            else
                inputState.quit = false;

            kPreviousState = kCurrentState;
            mPreviousState = mCurrentState;
            base.Update(gameTime);
        }

        public event Action<bool> OnShoot;
        public event Action<bool> OnSuperShoot;
        
    }
}
